<!--
<script src="http://protozoa.googlecode.com/svn/trunk/js/functions.js"></script>
<script src="http://protozoa.googlecode.com/svn/trunk/js/dom.js"></script>
<script src="http://protozoa.googlecode.com/svn/trunk/js/dom.event.js"></script>
<script src="http://protozoa.googlecode.com/svn/trunk/js/utils.js"></script>
-->

<script src="/js/functions.js"></script>
<script src="/js/dom.js"></script>
<script src="/js/dom.event.js"></script>
<script src="/js/utils.js"></script>
<script src="/js/debug.js"></script>
<!---->

<style>body {font-size:11px} pre {font:11px mono;border-bottom:1px solid #ddd; padding-bottom:0.3em; margin:0.3em;}</style>

<script src='lex3.js'></script>
<script>

/*
expr: NUMBER
expr: expr PLUS expr
expr: LP expr RP

pair: NUMBER NUMBER
*/

var parser = {
	description: '<INITIAL>',
	NUMBER: {
		description: 'expr -> NUMBER',
		reduce: ['expr', 1],
		NUMBER: {
			description: 'pair -> NUMBER NUMBER .',
			reduce: ['pair', 2]
		}
	},
	expr: {
		//description: 'program -> expr',
		//reduce: ['program', 1],
		description: 'expr . PLUS expr',
		PLUS: {
			description: 'expr -> expr PLUS . expr',
			expr: {
				description: 'expr -> expr PLUS expr . ',
				reduce: ['expr', 3]
			}
		}
	},
	LP: {
		description: 'expr -> LP . expr RP ',
		expr: {
			description: 'expr -> LP expr . RP ',
			RP: {
				description: 'expr -> LP expr RP .',
				reduce: ['expr', 3]
			}
		}
	}
};
//objoin(parser.LP, parser.expr);
//trace(parser);


//var input = ['NUMBER', 'NUMBER'];



var parse = function(parser, input) {
	var state = parser, s;
	var i = 0;
	var last_reducing_state;
	var last_reducing_pos;
	var max = input.length;
	var stack = [];
	var i0;
	var lhs;
	stack[0] = parser;
	var term;
	
	var cnt = 0;
	while (true) {
		if (++cnt > 100) { alert('Hang up'); return; }

		if (i >= max) break;
		
		term = input[i];
		trace('current symbol: ' + term + ' at position ' + i);
		state = stack[stack.length - 1];
		//state = stack.pop();
		s = state[term];
		if (!s) {
			trace('ERROR near ' + input[i] + ' ' + input[i+1]);
			break;
		}
		state = s;
		
		stack.push(state);
		
		if (state.reduce) {
			lhs = state.reduce[0];
			trace(state.description + ': reduce ' + lhs);
			for (var j = 0; j < state.reduce[1]; ++j)
				stack.pop();
			state = stack.pop();
			//trace('current state: ' + state.description);			
			state = state[lhs];
			trace('current state: ' + state.description);
			stack.push(state);
		} else {
			stack.push(parser);
		}
		
		++i;
	}
	return stack;
};


//parse(parser, ['LP', 'NUMBER', 'PLUS', 'NUMBER', 'RP']);
//parse(parser, ['LP', 'NUMBER', 'RP']);
trace(parse(parser, ['NUMBER', 'PLUS', 'NUMBER']));
//trace(parse(parser, ['NUMBER']));







</script>




















